home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pbm / libpbm1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-05  |  12.8 KB  |  683 lines

  1. /* libpbm1.c - pbm utility library part 1
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. */
  12.  
  13. #include <stdlib.h>
  14. #if __STDC__
  15. #include <stdarg.h>
  16. #else /*__STDC__*/
  17. #include <varargs.h>
  18. #endif /*__STDC__*/
  19.  
  20. #include "pbm.h"
  21. #include "version.h"
  22. #include "libpbm.h"
  23.  
  24. /* Forward routines. */
  25.  
  26. #if defined(NEED_VFPRINTF1) || defined(NEED_VFPRINTF2)
  27. int vfprintf ARGS(( FILE* stream, char* format, va_list args ));
  28. #endif /*NEED_VFPRINTF*/
  29.  
  30.  
  31. /* Variable-sized arrays. */
  32.  
  33. char*
  34. pm_allocrow( cols, size )
  35.     int cols;
  36.     int size;
  37.     {
  38.     register char* itrow;
  39.  
  40.     itrow = (char*) malloc( cols * size );
  41.     if ( itrow == (char*) 0 )
  42.     pm_error( "out of memory allocating a row" );
  43.     return itrow;
  44.     }
  45.  
  46. void
  47. pm_freerow( itrow )
  48.     char* itrow;
  49.     {
  50.     free( itrow );
  51.     }
  52.  
  53.  
  54. char**
  55. pm_allocarray( cols, rows, size )
  56.     int cols, rows;
  57.     int size;
  58.     {
  59.     char** its;
  60.     int i;
  61.  
  62.     its = (char**) malloc( rows * sizeof(char*) );
  63.     if ( its == (char**) 0 )
  64.     pm_error( "out of memory allocating an array" );
  65.     its[0] = (char*) malloc( rows * cols * size );
  66.     if ( its[0] == (char*) 0 )
  67.     pm_error( "out of memory allocating an array" );
  68.     for ( i = 1; i < rows; ++i )
  69.     its[i] = &(its[0][i * cols * size]);
  70.     return its;
  71.     }
  72.  
  73. void
  74. pm_freearray( its, rows )
  75.     char** its;
  76.     int rows;
  77.     {
  78.     free( its[0] );
  79.     free( its );
  80.     }
  81.  
  82.  
  83. /* Case-insensitive keyword matcher. */
  84.  
  85. int
  86. pm_keymatch( str, keyword, minchars )
  87.     char* str;
  88.     char* keyword;
  89.     int minchars;
  90.     {
  91.     register int len;
  92.  
  93.     len = strlen( str );
  94.     if ( len < minchars )
  95.     return 0;
  96.     while ( --len >= 0 )
  97.     {
  98.     register char c1, c2;
  99.  
  100.     c1 = *str++;
  101.     c2 = *keyword++;
  102.     if ( c2 == '\0' )
  103.         return 0;
  104.     if ( isupper( c1 ) )
  105.         c1 = tolower( c1 );
  106.     if ( isupper( c2 ) )
  107.         c1 = tolower( c2 );
  108.     if ( c1 != c2 )
  109.         return 0;
  110.     }
  111.     return 1;
  112.     }
  113.  
  114.  
  115. /* Log base two hacks. */
  116.  
  117. int
  118. pm_maxvaltobits( maxval )
  119.     int maxval;
  120.     {
  121.     if ( maxval <= 1 )
  122.     return 1;
  123.     else if ( maxval <= 3 )
  124.     return 2;
  125.     else if ( maxval <= 7 )
  126.     return 3;
  127.     else if ( maxval <= 15 )
  128.     return 4;
  129.     else if ( maxval <= 31 )
  130.     return 5;
  131.     else if ( maxval <= 63 )
  132.     return 6;
  133.     else if ( maxval <= 127 )
  134.     return 7;
  135.     else if ( maxval <= 255 )
  136.     return 8;
  137.     else if ( maxval <= 511 )
  138.     return 9;
  139.     else if ( maxval <= 1023 )
  140.     return 10;
  141.     else if ( maxval <= 2047 )
  142.     return 11;
  143.     else if ( maxval <= 4095 )
  144.     return 12;
  145.     else if ( maxval <= 8191 )
  146.     return 13;
  147.     else if ( maxval <= 16383 )
  148.     return 14;
  149.     else if ( maxval <= 32767 )
  150.     return 15;
  151.     else if ( (long) maxval <= 65535L )
  152.     return 16;
  153.     else
  154.     pm_error( "maxval of %d is too large!", maxval );
  155.     }
  156.  
  157. int
  158. pm_bitstomaxval( bits )
  159.     int bits;
  160.     {
  161.     return ( 1 << bits ) - 1;
  162.     }
  163.  
  164.  
  165. /* Initialization. */
  166.  
  167. static char* progname;
  168. static int showmessages;
  169.  
  170. void
  171. pm_init( argcP, argv )
  172.     int* argcP;
  173.     char* argv[];
  174.     {
  175.     int argn, i;
  176.  
  177.     /* Extract program name. */
  178.     progname = rindex( argv[0], '/');
  179.     if ( progname == NULL )
  180.     progname = argv[0];
  181.     else
  182.     ++progname;
  183.  
  184.     /* Check for any global args. */
  185.     showmessages = 1;
  186.     for ( argn = 1; argn < *argcP; ++argn )
  187.     {
  188.     if ( pm_keymatch( argv[argn], "-quiet", 6 ) )
  189.         {
  190.         showmessages = 0;
  191.         }
  192.     else if ( pm_keymatch( argv[argn], "-version", 7 ) )
  193.         {
  194.         pm_message( "Version of %s", PBMPLUS_VERSION );
  195. #ifdef BSD
  196.         pm_message( "BSD defined" );
  197. #endif /*BSD*/
  198. #ifdef SYSV
  199.         pm_message( "SYSV defined" );
  200. #endif /*SYSV*/
  201. #ifdef MSDOS
  202.         pm_message( "MSDOS defined" );
  203. #endif /*MSDOS*/
  204. #ifdef PBMPLUS_RAWBITS
  205.         pm_message( "PBMPLUS_RAWBITS defined" );
  206. #endif /*PBMPLUS_RAWBITS*/
  207. #ifdef PBMPLUS_BROKENPUTC1
  208.         pm_message( "PBMPLUS_BROKENPUTC1 defined" );
  209. #endif /*PBMPLUS_BROKENPUTC1*/
  210. #ifdef PBMPLUS_BROKENPUTC2
  211.         pm_message( "PBMPLUS_BROKENPUTC2 defined" );
  212. #endif /*PBMPLUS_BROKENPUTC2*/
  213. #ifdef PGM_BIGGRAYS
  214.         pm_message( "PGM_BIGGRAYS defined" );
  215. #endif /*PGM_BIGGRAYS*/
  216. #ifdef PPM_PACKCOLORS
  217.         pm_message( "PPM_PACKCOLORS defined" );
  218. #endif /*PPM_PACKCOLORS*/
  219. #ifdef DEBUG
  220.         pm_message( "DEBUG defined" );
  221. #endif /*DEBUG*/
  222. #ifdef NEED_VFPRINTF1
  223.         pm_message( "NEED_VFPRINTF1 defined" );
  224. #endif /*NEED_VFPRINTF1*/
  225. #ifdef NEED_VFPRINTF2
  226.         pm_message( "NEED_VFPRINTF2 defined" );
  227. #endif /*NEED_VFPRINTF2*/
  228. #ifdef RGB_DB
  229.         pm_message( "RGB_DB=\"%s\"", RGB_DB );
  230. #endif /*RGB_DB*/
  231. #ifdef LIBTIFF
  232.         pm_message( "LIBTIFF defined" );
  233. #endif /*LIBTIFF*/
  234.         exit( 0 );
  235.         }
  236.     else
  237.         continue;
  238.     for ( i = argn + 1; i <= *argcP; ++i )
  239.         argv[i - 1] = argv[i];
  240.     --(*argcP);
  241.     }
  242.     }
  243.  
  244. void
  245. pbm_init( argcP, argv )
  246.     int* argcP;
  247.     char* argv[];
  248.     {
  249.     pm_init( argcP, argv );
  250.     }
  251.  
  252.  
  253. /* Error handling. */
  254.  
  255. void
  256. pm_usage( usage )
  257.     char* usage;
  258.     {
  259.     fprintf( stderr, "usage:  %s %s\n", progname, usage );
  260.     exit( 1 );
  261.     }
  262.  
  263. void
  264. pm_perror( reason )
  265.     char* reason;
  266.     {
  267.     char* e;
  268.  
  269. #ifdef sys_errlist
  270.     e = sys_errlist[errno];
  271. #else
  272.     e = strerror (errno);
  273. #endif
  274.     if ( reason != 0 && reason[0] != '\0' )
  275.     pm_error( "%s - %s", reason, e );
  276.     else
  277.     pm_error( "%s", e );
  278.     }
  279.  
  280. #if __STDC__
  281. void
  282. pm_message( char* format, ... )
  283.     {
  284.     va_list args;
  285.  
  286.     va_start( args, format );
  287. #else /*__STDC__*/
  288. /*VARARGS1*/
  289. void
  290. pm_message( va_alist )
  291.     va_dcl
  292.     { /*}*/
  293.     va_list args;
  294.     char* format;
  295.  
  296.     va_start( args );
  297.     format = va_arg( args, char* );
  298. #endif /*__STDC__*/
  299.  
  300.     if ( showmessages )
  301.     {
  302.     fprintf( stderr, "%s: ", progname );
  303.     (void) vfprintf( stderr, format, args );
  304.     fputc( '\n', stderr );
  305.     }
  306.     va_end( args );
  307.     }
  308.  
  309. #if __STDC__
  310. void
  311. pm_error( char* format, ... )
  312.     {
  313.     va_list args;
  314.  
  315.     va_start( args, format );
  316. #else /*__STDC__*/
  317. /*VARARGS1*/
  318. void
  319. pm_error( va_alist )
  320.     va_dcl
  321.     { /*}*/
  322.     va_list args;
  323.     char* format;
  324.  
  325.     va_start( args );
  326.     format = va_arg( args, char* );
  327. #endif /*__STDC__*/
  328.  
  329.     fprintf( stderr, "%s: ", progname );
  330.     (void) vfprintf( stderr, format, args );
  331.     fputc( '\n', stderr );
  332.     va_end( args );
  333.     exit( 1 );
  334.     }
  335.  
  336. #ifdef NEED_VFPRINTF1
  337.  
  338. /* Micro-vfprintf, for systems that don't have vfprintf but do have _doprnt.
  339. */
  340.  
  341. int
  342. vfprintf( stream, format, args )
  343.     FILE* stream;
  344.     char* format;
  345.     va_list args;
  346.     {
  347.     return _doprnt( format, args, stream );
  348.     }
  349. #endif /*NEED_VFPRINTF1*/
  350.  
  351. #ifdef NEED_VFPRINTF2
  352.  
  353. /* Portable mini-vfprintf, for systems that don't have either vfprintf or
  354. ** _doprnt.  This depends only on fprintf.  If you don't have fprintf,
  355. ** you might consider getting a new stdio library.
  356. */
  357.  
  358. int
  359. vfprintf( stream, format, args )
  360.     FILE* stream;
  361.     char* format;
  362.     va_list args;
  363.     {
  364.     int n;
  365.     char* ep;
  366.     char fchar;
  367.     char tformat[512];
  368.     int do_long;
  369.     int i;
  370.     long l;
  371.     unsigned u;
  372.     unsigned long ul;
  373.     char* s;
  374.     double d;
  375.  
  376.     n = 0;
  377.     while ( *format != '\0' )
  378.     {
  379.     if ( *format != '%' )
  380.         { /* Not special, just write out the char. */
  381.         (void) putc( *format, stream );
  382.         ++n;
  383.         ++format;
  384.         }
  385.     else
  386.         {
  387.         do_long = 0;
  388.         ep = format + 1;
  389.  
  390.         /* Skip over all the field width and precision junk. */
  391.         if ( *ep == '-' )
  392.         ++ep;
  393.         if ( *ep == '0' )
  394.         ++ep;
  395.         while ( isdigit( *ep ) )
  396.         ++ep;
  397.         if ( *ep == '.' )
  398.         {
  399.         ++ep;
  400.         while ( isdigit( *ep ) )
  401.             ++ep;
  402.         }
  403.         if ( *ep == '#' )
  404.         ++ep;
  405.         if ( *ep == 'l' )
  406.         {
  407.         do_long = 1;
  408.         ++ep;
  409.         }
  410.  
  411.         /* Here's the field type.  Extract it, and copy this format
  412.         ** specifier to a temp string so we can add an end-of-string.
  413.         */
  414.         fchar = *ep;
  415.         (void) strncpy( tformat, format, ep - format + 1 );
  416.         tformat[ep - format + 1] = '\0';
  417.  
  418.         /* Now do a one-argument fprintf with the format string we have
  419.         ** isolated.
  420.         */
  421.         switch ( fchar )
  422.         {
  423.         case 'd':
  424.         if ( do_long )
  425.             {
  426.             l = va_arg( args, long );
  427.             n += fprintf( stream, tformat, l );
  428.             }
  429.         else
  430.             {
  431.             i = va_arg( args, int );
  432.             n += fprintf( stream, tformat, i );
  433.             }
  434.         break;
  435.  
  436.             case 'o':
  437.             case 'x':
  438.             case 'X':
  439.             case 'u':
  440.         if ( do_long )
  441.             {
  442.             ul = va_arg( args, unsigned long );
  443.             n += fprintf( stream, tformat, ul );
  444.             }
  445.         else
  446.             {
  447.             u = va_arg( args, unsigned );
  448.             n += fprintf( stream, tformat, u );
  449.             }
  450.         break;
  451.  
  452.             case 'c':
  453.         i = (char) va_arg( args, int );
  454.         n += fprintf( stream, tformat, i );
  455.         break;
  456.  
  457.             case 's':
  458.         s = va_arg( args, char* );
  459.         n += fprintf( stream, tformat, s );
  460.         break;
  461.  
  462.             case 'e':
  463.             case 'E':
  464.             case 'f':
  465.             case 'g':
  466.             case 'G':
  467.         d = va_arg( args, double );
  468.         n += fprintf( stream, tformat, d );
  469.         break;
  470.  
  471.             case '%':
  472.         (void) putc( '%', stream );
  473.         ++n;
  474.         break;
  475.  
  476.         default:
  477.         return -1;
  478.         }
  479.  
  480.         /* Resume formatting on the next character. */
  481.         format = ep + 1;
  482.         }
  483.     }
  484.     return nc;
  485.     }
  486. #endif /*NEED_VFPRINTF2*/
  487.  
  488.  
  489. /* File open/close that handles "-" as stdin and checks errors. */
  490.  
  491. FILE*
  492. pm_openr( name )
  493.     char* name;
  494.     {
  495.     FILE* f;
  496.  
  497.     if ( strcmp( name, "-" ) == 0 )
  498.     f = stdin;
  499.     else
  500.     {
  501. #ifdef MSDOS
  502.     f = fopen( name, "rb" );
  503. #else /*MSDOS*/
  504.     f = fopen( name, "r" );
  505. #endif /*MSDOS*/
  506.     if ( f == NULL )
  507.         {
  508.         pm_perror( name );
  509.         exit( 1 );
  510.         }
  511.     }
  512.     return f;
  513.     }
  514.  
  515. FILE*
  516. pm_openw( name )
  517.     char* name;
  518.     {
  519.     FILE* f;
  520.  
  521. #ifdef MSDOS
  522.     f = fopen( name, "wb" );
  523. #else /*MSDOS*/
  524.     f = fopen( name, "w" );
  525. #endif /*MSDOS*/
  526.     if ( f == NULL )
  527.     {
  528.     pm_perror( name );
  529.     exit( 1 );
  530.     }
  531.     return f;
  532.     }
  533.  
  534. void
  535. pm_close( f )
  536.     FILE* f;
  537.     {
  538.     fflush( f );
  539.     if ( ferror( f ) )
  540.     pm_message( "a file read or write error occurred at some point" );
  541. #ifdef MSDOS
  542.     if (f == stdout) {
  543.         return;
  544.     }
  545. #endif
  546.     if ( f != stdin )
  547.     if ( fclose( f ) != 0 )
  548.         pm_error( "fclose" );
  549.     }
  550.  
  551. /* Endian I/O.
  552. */
  553.  
  554. int
  555. pm_readbigshort( in, sP )
  556.     FILE* in;
  557.     short* sP;
  558.     {
  559.     int c;
  560.  
  561.     if ( (c = getc( in )) == EOF )
  562.     return -1;
  563.     *sP = ( c & 0xff ) << 8;
  564.     if ( (c = getc( in )) == EOF )
  565.     return -1;
  566.     *sP |= c & 0xff;
  567.     return 0;
  568.     }
  569.  
  570. #if __STDC__
  571. int
  572. pm_writebigshort( FILE* out, short s )
  573. #else /*__STDC__*/
  574. int
  575. pm_writebigshort( out, s )
  576.     FILE* out;
  577.     short s;
  578. #endif /*__STDC__*/
  579.     {
  580.     (void) putc( ( s >> 8 ) & 0xff, out );
  581.     (void) putc( s & 0xff, out );
  582.     return 0;
  583.     }
  584.  
  585. int
  586. pm_readbiglong( in, lP )
  587.     FILE* in;
  588.     long* lP;
  589.     {
  590.     int c;
  591.  
  592.     if ( (c = getc( in )) == EOF )
  593.     return -1;
  594.     *lP = ( c & 0xff ) << 24;
  595.     if ( (c = getc( in )) == EOF )
  596.     return -1;
  597.     *lP |= ( c & 0xff ) << 16;
  598.     if ( (c = getc( in )) == EOF )
  599.     return -1;
  600.     *lP |= ( c & 0xff ) << 8;
  601.     if ( (c = getc( in )) == EOF )
  602.     return -1;
  603.     *lP |= c & 0xff;
  604.     return 0;
  605.     }
  606.  
  607. int
  608. pm_writebiglong( out, l )
  609.     FILE* out;
  610.     long l;
  611.     {
  612.     (void) putc( ( l >> 24 ) & 0xff, out );
  613.     (void) putc( ( l >> 16 ) & 0xff, out );
  614.     (void) putc( ( l >> 8 ) & 0xff, out );
  615.     (void) putc( l & 0xff, out );
  616.     return 0;
  617.     }
  618.  
  619. int
  620. pm_readlittleshort( in, sP )
  621.     FILE* in;
  622.     short* sP;
  623.     {
  624.     int c;
  625.  
  626.     if ( (c = getc( in )) == EOF )
  627.     return -1;
  628.     *sP = c & 0xff;
  629.     if ( (c = getc( in )) == EOF )
  630.     return -1;
  631.     *sP |= ( c & 0xff ) << 8;
  632.     return 0;
  633.     }
  634.  
  635. #if __STDC__
  636. int
  637. pm_writelittleshort( FILE* out, short s )
  638. #else /*__STDC__*/
  639. int
  640. pm_writelittleshort( out, s )
  641.     FILE* out;
  642.     short s;
  643. #endif /*__STDC__*/
  644.     {
  645.     (void) putc( s & 0xff, out );
  646.     (void) putc( ( s >> 8 ) & 0xff, out );
  647.     return 0;
  648.     }
  649.  
  650. int
  651. pm_readlittlelong( in, lP )
  652.     FILE* in;
  653.     long* lP;
  654.     {
  655.     int c;
  656.  
  657.     if ( (c = getc( in )) == EOF )
  658.     return -1;
  659.     *lP = c & 0xff;
  660.     if ( (c = getc( in )) == EOF )
  661.     return -1;
  662.     *lP |= ( c & 0xff ) << 8;
  663.     if ( (c = getc( in )) == EOF )
  664.     return -1;
  665.     *lP |= ( c & 0xff ) << 16;
  666.     if ( (c = getc( in )) == EOF )
  667.     return -1;
  668.     *lP |= ( c & 0xff ) << 24;
  669.     return 0;
  670.     }
  671.  
  672. int
  673. pm_writelittlelong( out, l )
  674.     FILE* out;
  675.     long l;
  676.     {
  677.     (void) putc( l & 0xff, out );
  678.     (void) putc( ( l >> 8 ) & 0xff, out );
  679.     (void) putc( ( l >> 16 ) & 0xff, out );
  680.     (void) putc( ( l >> 24 ) & 0xff, out );
  681.     return 0;
  682.     }
  683.